#include "key.h"   
#include "usart.h"
#include "stdbool.h"

/*
KEY_STATUS_ENUM(STATUS) --> STATUS(KS_RELEASE) ... STATUS(KS_NUM)

KEY_STATUS_ENUM(ENUM_ITEM)
--> ENUM_ITEM(KS_RELEASE) ... ENUM_ITEM(KS_NUM)
--> KS_RELEASE, ... KS_NUM,

KEY_STATUS_ENUM(ENUM_STRING)
--> ENUM_STRING(KS_RELEASE) ... ENUM_STRING(KS_NUM)
--> #KS_RELEASE, ... #KS_NUM,
*/
typedef enum
{
	KEY_STATUS_ENUM(ENUM_ITEM)
}KEY_STATUS;

const char* key_status_name[] = {
	KEY_STATUS_ENUM(ENUM_STRING)
};

typedef struct {
	KEY_STATUS keyStatus;
	KEY_STATUS nowKeyStatus;
	KEY_STATUS lastKeyStatus;
	int keyIdx;
}KeyFsmData;

void multi_key_check_init();

void KEY_Init(void)
{
 
//	GPIO_InitTypeDef  GPIO_InitStructure;
//
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);

	multi_key_check_init();
}

bool key_press_check(KeyFsmData *pKeyFsmData)
{
	bool bPress = false;

	switch(pKeyFsmData->keyStatus)
	{
		case KS_RELEASE:
		{
			if (KEY(pKeyFsmData->keyIdx) == 0)
			{
				pKeyFsmData->keyStatus = KS_SHAKE;
			}
		}
		break;
		
		case KS_SHAKE:
		{
			if (KEY(pKeyFsmData->keyIdx) == 1)
			{
				pKeyFsmData->keyStatus = KS_RELEASE;
				if (KS_PRESS == pKeyFsmData->lastKeyStatus)
				{
//					printf("=====> key release\r\n");
				}
			}
			else
			{
				pKeyFsmData->keyStatus = KS_PRESS;
				if (KS_RELEASE == pKeyFsmData->lastKeyStatus)
				{
//					printf("=====> key press\r\n");
					bPress = true;
				}
			}
		}
		break;
		
		case KS_PRESS:
		{
			if (KEY(pKeyFsmData->keyIdx) == 1)
			{
				pKeyFsmData->keyStatus = KS_SHAKE;
			}
		}
		break;
		
		default:break;
	}

	if (pKeyFsmData->keyStatus != pKeyFsmData->nowKeyStatus)
	{
		pKeyFsmData->lastKeyStatus = pKeyFsmData->nowKeyStatus;
		pKeyFsmData->nowKeyStatus = pKeyFsmData->keyStatus;
//		printf("new key status:%d(%s)\r\n", pKeyFsmData->keyStatus, key_status_name[pKeyFsmData->keyStatus]);
	}

	return bPress;
}

/////////////////////////////////////////////
KeyFsmData pKey0FsmData;
KeyFsmData pKey1FsmData;
KeyFsmData pKey2FsmData;
KeyFsmData pKey3FsmData;

void key_check_init(KeyFsmData *pKeyFsmData, int keyIdx)
{
	pKeyFsmData->keyStatus = KS_RELEASE;
	pKeyFsmData->lastKeyStatus = KS_RELEASE;
	pKeyFsmData->nowKeyStatus = KS_RELEASE;
	pKeyFsmData->keyIdx = keyIdx;
}

void multi_key_check_init()
{
	key_check_init(&pKey0FsmData, 0);
	key_check_init(&pKey1FsmData, 1);
	key_check_init(&pKey2FsmData, 2);
	key_check_init(&pKey3FsmData, 3);
}

__IO int g_keyPressIdx = -1;
void multi_key_check()
{
	bool key0 = key_press_check(&pKey0FsmData);
	bool key1 = key_press_check(&pKey1FsmData);
	bool key2 = key_press_check(&pKey2FsmData);
	bool key3 = key_press_check(&pKey3FsmData);

	if (key0 || key1 || key2 || key3)
	{
//		printf("key0:%d, key1:%d, key2:%d, key3:%d, \r\n", key0, key1, key2, key3);

		if (key0)
		{
			g_keyPressIdx = 0;
		}
		else if (key1)
		{
			g_keyPressIdx = 1;
		}
		else if (key2)
		{
			g_keyPressIdx = 2;
		}
		else if (key3)
		{
			g_keyPressIdx = 3;
		}
	}
}

int get_press_key_idx()
{
	int idx = g_keyPressIdx;
	g_keyPressIdx = -1;
	
	return idx;
}
